﻿using Models;
using QRCoder;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommTestNFW.ImageCode
{
    public class CodeHeplerBak
    {
        /// <summary>
        /// 拼接LabNo
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string Join(PrintLabNo model)
        {
            var week = model.Week == 6 ? "6" : "";

            var fullYear = (20 * 100) + model.Year;// 2000 + 20 = 2020年
            var date = new DateTime(fullYear, model.Month, 1);
            var monthE = date.ToString("MMMM", new CultureInfo("en-us")).Substring(0, 1);

            //ZM20P07J60001
            //ZM20P07J0001
            model.LabNo = model.Custom + model.Year + model.SpecimenType + model.Month.ToString("D2") + monthE + week + model.Counter.ToString("D4");
            return model.LabNo;
        }

        public static IEnumerable<PrintLabNo> GetPrintLabNos(int len)
        {
            if (len == 0)
            {
                yield return null;
            }
            var date = DateTime.Now;
            string template = "ZM20{0}06J{1}{2}";
            var random = new Random();
            for (int i = 1; i <= len; i++)
            {
                int r = random.Next(1, 12);
                string p = r % 2 == 0 ? "P" : "";
                int week = r % 3 == 0 ? 6 : 7;
                var fullYear = date.Year;// 2000 + 20 = 2020年
                var labNo= new PrintLabNo() {
                    Counter = i,
                    Custom = "ZM",
                    Year = fullYear - 2000,
                    Month = date.Month,
                    SpecimenType = p,
                    Week = week
                };
                Join(labNo);
                yield return labNo;
                yield return labNo;
                yield return labNo;
            }
        }
        public static IEnumerable<string> GetCodes(int len)
        {
            if (len == 0)
            {
                yield return null;
            }
            string template = "ZM20{0}06J{1}{2}";
            for (int i = 1; i <= len; i++)
            {
                string serial = i.ToString("0000");
                string p = i % 2 == 0 ? "P" : "";
                string six = i % 2 == 0 ? "6" : "";
                string code = string.Format(template, p, six, serial);

                yield return code;
                yield return code;
                yield return code;
            }
        }

        private static void SetCode(IEnumerable<PrintLabNo> codes, CodePage page)
        {
            var enumerator = codes.GetEnumerator();
            //enumerator.Reset();
            int i = 0, len = page.CodeLabels.Length;
            while (enumerator.MoveNext() && i < len)
            {
                page.CodeLabels[i++].PrintLabNo = enumerator.Current;
            }

        }

        public static string path = "D:/test/print-img";

        public static string Build()
        {

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var codes = GetPrintLabNos(216);


            int width = 2030;
            int heigth = 1400;
            Bitmap bitmap = new Bitmap(width, heigth);

            //构建绘图对象
            var gm = GraphicsManagement.Build(bitmap);
            //构建页面对象
            var page = new CodePage(width, heigth);
            SetCode(codes, page);
            foreach (var label in page.CodeLabels)
            {
                //draw background
                gm.Graphics.FillRectangle(gm.BrushWhite, new Rectangle(label.Point, label.Size));

                MakeCode(gm, label);
            }

            string imageOriginPath = $"{path}/test-origin.jpg";
            bitmap.Save(imageOriginPath);
            
            string imagePath = $"{path}/test.jpg";
            bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
            bitmap.Save(imagePath);

            bitmap.Dispose();

            return imagePath;
        }

        public static void Build2()
        {

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var codes = GetCodes(0);
            codes.Count();

            int width = 2030;
            int heigth = 1400;
            Bitmap bitmap = new Bitmap(width, heigth);


            var gm = GraphicsManagement.Build(bitmap);

            int cols = 24;
            int rows = 9;
            int pageRealWidth = 10;//mm
            int pageRealHeight = 20;//mm
            int pageRealGap = 2;//mm
            int pageRealPadding = 2;
            //总宽 mm
            int widthP = pageRealWidth * cols + pageRealGap * (cols - 1) + pageRealPadding * 2;

            //每mm所占像素
            int pixel = width / widthP;

            int gap = pageRealGap * pixel;//2mm * 10   2*25
            int padding = pageRealPadding * pixel;
            int pageWidth = pageRealWidth * pixel;//10mm
            int pageHeight = pageRealHeight * pixel;//20mm

            int x1 = padding;
            int y1 = padding;

            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    var code = codes.Take(i + j).FirstOrDefault();
                    if (string.IsNullOrWhiteSpace(code))
                        continue;

                    int row = i;
                    int col = j;
                    int x = x1 + col * (pageWidth + gap);
                    int y = y1 + row * (pageHeight + gap);
                    var p = new Point(x, y);

                    //draw background
                    gm.SetColor(Color.White);
                    gm.Graphics.FillRectangle(gm.Brush, new Rectangle(x, y, pageWidth, pageHeight));

                    MakeCode(gm, code, p, pageWidth, pageHeight);
                }
            }

            string imagePath = $"{path}/test.jpg";
            bitmap.Save(imagePath);

            bitmap.Dispose();
        }

        public static void MakeCode(GraphicsManagement gm, CodeLabel label)
        {
            var code = label.Code;
            if (!string.IsNullOrWhiteSpace(code))
            {
                Brush brush = label.Brush;
                Graphics g = gm.Graphics;
                Font font = gm.Font;

                //单个字母的长度
                int characterWidth = (int)font.Size;
                //单个字母的偏移量
                int offset = characterWidth / 2;
                int max = CodeLabel.RowMaxLen;
                LineText line1 = label.Line1Text;
                LineText line2 = label.Line2Text;
                var p = label.InnerPoint;
                var p1 = new Point(p.X + (max - line1.Length) * offset, p.Y + 8);
                var p2 = new Point(p.X + (max - line2.Length) * offset, p.Y + 20 + 12);
                g.DrawString(line1.Text, font, brush, p1);
                g.DrawString(line2.Text, font, brush, p2);

                var size = label.InnerSize;

                Bitmap codeImage = MakeQrCode(code);
                g.DrawImage(codeImage, new RectangleF(p.X, p.Y + size.Height - size.Width, label.QrCode.Width, label.QrCode.Height));
            }
        }

        public static void MakeCode(GraphicsManagement gm, string code, Point p, int pageWidth, int pageHeight)
        {
            gm.SetColor(Color.Black);
            Brush brush = gm.Brush;
            Graphics g = gm.Graphics;
            Font font = gm.Font;

            string code1 = code.Substring(4, 4);
            string code2 = code.Substring(8);

            var p1 = new Point(p.X, p.Y);
            var p2 = new Point(p.X, p.Y + 20);
            g.DrawString(code1, font, brush, p1);
            g.DrawString(code2, font, brush, p2);

            Bitmap codeImage = MakeQrCode(code);
            g.DrawImage(codeImage, new RectangleF(p.X, p.Y + pageHeight - pageWidth, pageWidth, pageWidth));
        }


        public static Bitmap MakeQrCode(string code, int pixel = 72)
        {
            QRCodeGenerator generator = new QRCodeGenerator();

            QRCodeData qRCodeData = generator.CreateQrCode(code, QRCodeGenerator.ECCLevel.H);
            QRCode qRCode = new QRCode(qRCodeData);
            return qRCode.GetGraphic(pixel, Color.Black, Color.White, false);
        }

    }
}
